package fr.ups.jim.isi.tp5 ;

import fr.lri.swingstates.canvas.Canvas ;
import fr.lri.swingstates.canvas.CStateMachine ;
import fr.lri.swingstates.canvas.CExtensionalTag ;
import fr.lri.swingstates.canvas.CShape ;
import fr.lri.swingstates.canvas.CRectangle ;
import fr.lri.swingstates.canvas.CText ;
import fr.lri.swingstates.debug.StateMachineVisualization ;
import fr.lri.swingstates.sm.State ;
import fr.lri.swingstates.sm.Transition ;
import fr.lri.swingstates.sm.transitions.* ;

import javax.swing.JFrame ;
import java.awt.Color ;
import java.awt.BasicStroke ;
import java.awt.Font ;

/**
 * @author Nicolas Roussel (roussel@lri.fr)
 *
 */
public class SimpleButton {

    private CExtensionalTag tag ;
    private CRectangle rect ;
    private CText label ;
    private CStateMachine mach ;

    private int padding = 5 ;
    private int[] borderwidth = {1, 2} ;
    private Color[] color = {Color.WHITE, Color.YELLOW} ;

    SimpleButton(Canvas canvas, String text) {
	   this(canvas, text, CStateMachine.BUTTON1, CStateMachine.NOMODIFIER) ;
    }

    SimpleButton(Canvas canvas, String text,
			  final int button, final int modifier) {
	   tag = new CExtensionalTag(canvas) {} ;
	   label = canvas.newText(0, 0, text, new Font("verdana", Font.PLAIN, 12)) ;
	   label.setPickable(false) ;
	   rect = canvas.newRectangle(label.getMinX()-padding,
							label.getMinY()-padding,
							label.getWidth()+2*padding,
							label.getHeight()+2*padding) ;
	   rect.below(label).setParent(label) ;
	   rect.addTag(tag) ;
	   rect.setStroke(new BasicStroke(borderwidth[0])).setFillPaint(color[0]) ;

	   mach = new CStateMachine() {

			 public State idle = new State() {
				    Transition toOver = new EnterOnTag(tag, ">> over") {} ;
				} ;

			 public State over = new State() {
				    public void enter() {
					   rect.setStroke(new BasicStroke(borderwidth[1])) ;
				    }
				    Transition leave = new LeaveOnTag(tag, ">> idle") {} ;
				    Transition arm = new Press(button, modifier, ">> armed") {} ;
				    public void leave() {
					   rect.setStroke(new BasicStroke(borderwidth[0])) ;
				    }
				} ;

			 public State armed = new State() {
				    public void enter() {
					   rect.setFillPaint(color[1]) ;
					   rect.setStroke(new BasicStroke(borderwidth[1])) ;
				    }
				    Transition disarm = new LeaveOnTag(tag, ">> disarmed") {} ;
				    Transition act = new Release(button, modifier, ">> over") {
						  public void action() {
							 SimpleButton.this.doClick() ;
						  }
					   } ;
				    public void leave() {
					   rect.setFillPaint(color[0]) ;
					   rect.setStroke(new BasicStroke(borderwidth[0])) ;
				    }
				} ;

			 public State disarmed = new State() {
				    public void enter() {
					   rect.setFillPaint(color[1]) ;
				    }
				    Transition rearm = new EnterOnTag(tag, ">> armed") {} ;
				    Transition cancel = new Release(button, modifier, ">> idle") {} ;
				    public void leave() {
					   rect.setFillPaint(color[0]) ;
				    }
				} ;

		  } ;
	   mach.attachTo(canvas) ;
    }

    public void doClick() {
	   System.out.println("CLICK!") ;
    }

    public CShape getShape() {
	   return label ;
    }

    public void showMachine() {
	   JFrame viz = new JFrame() ;
	   viz.getContentPane().add(new StateMachineVisualization(mach)) ;
	   viz.pack() ;
	   viz.setVisible(true) ;
    }

    static public void main(String[] args) {
	   JFrame frame = new JFrame() ;
	   Canvas canvas = new Canvas(400,400) ;
	   frame.getContentPane().add(canvas) ;
	   frame.pack() ;
	   frame.setVisible(true) ;

	   SimpleButton simple = new SimpleButton(canvas, "simple") ;
	   simple.getShape().translateBy(100,100) ;
	   simple.showMachine() ;

	   SimpleButton morecomplex = new SimpleButton(canvas,
										  "control-1",
										  CStateMachine.BUTTON1, 
										  CStateMachine.CONTROL) {
			 public void doClick() {
				System.out.println("BINGO!") ;
			 }
		  } ;
	   morecomplex.getShape().translateBy(200,100) ;
    }

}
